using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using GriffinNav.GPS;

namespace GriffinNav.UI
{
    public class AppSettings
    {
        #region AppSettings.xml Document Format
        //  <?xml version="1.0" encoding="utf-8" ?>
        //  <configuration>
        //      <appSettings>
        //          <add key="GpsPort" value="" />
        //          <add key="GpsBaudRate" value="" />
        //          <add key="UnitSystem" value="" />
        //      </appSettings>
        //      <appState>
        //          <add key="MapViewLastLatitude" value="" />
        //          <add key="MapViewLastLongitude" value="" />
        //          <add key="MapViewLastMapPath" value="" />
        //      </appState>
        //  </configuration>
        #endregion

        private static Dictionary<string, string> mSettings;
        private static string mSettingsPath;

        static AppSettings()
        {
            try
            {
                // set the app settings file path
                mSettingsPath = Path.Combine(Global.AppPath, "AppSettings.xml");

                // check if the file exists
                if (!File.Exists(mSettingsPath))
                {
                    Cursor.Current = Cursors.WaitCursor;

                    // create a new settings file in the application root
                    createSettingsFile();
                }

                XmlDocument xml = new XmlDocument();

                // load the settings xml
                xml.Load(mSettingsPath);

                // get only application settings
                XmlNodeList nodes = xml.SelectSingleNode("//configuration/appSettings").ChildNodes;
                mSettings = new Dictionary<string, string>();

                // load application settings into collection
                foreach (XmlNode node in nodes)
                {
                    mSettings.Add(node.Attributes["key"].Value, node.Attributes["value"].Value);
                }
            }
            catch (Exception ex)
            {
                Global.ShowError("Error", ex.Message);
            }

            Cursor.Current = Cursors.Default;
        }

        public static string GpsPort
        {
            get
            {
                if (!mSettings.ContainsKey("GpsPort"))
                {
                    mSettings.Add("GpsPort", string.Empty);

                    return string.Empty;
                }

                return mSettings["GpsPort"];
            }
            set
            {
                mSettings["GpsPort"] = value;
            }
        }

        public static int GpsBaudRate
        {
            get
            {
                if (!mSettings.ContainsKey("GpsBaudRate"))
                {
                    mSettings.Add("GpsBaudRate", "");
                    return 0;
                }
                else if (string.IsNullOrEmpty(mSettings["GpsBaudRate"]))
                {
                    return 0;
                }

                return int.Parse(mSettings["GpsBaudRate"]);
            }
            set
            {
                mSettings["GpsBaudRate"] = value.ToString();
            }
        }

        public static int GpsReadTimeout
        {
            get
            {
                if (!mSettings.ContainsKey("GpsReadTimeout"))
                {
                    mSettings.Add("GpsReadTimeout", "");
                    return 30;
                }
                else if (string.IsNullOrEmpty(mSettings["GpsReadTimeout"]))
                {
                    return 30;
                }

                return int.Parse(mSettings["GpsReadTimeout"]);
            }
            set
            {
                mSettings["GpsReadTimeout"] = value.ToString();
            }
        }

        public static UnitSystem UnitSystem
        {
            get
            {
                if (!mSettings.ContainsKey("UnitSystem"))
                {
                    mSettings.Add("UnitSystem", "metric");
                    return UnitSystem.Metric;
                }

                switch (mSettings["UnitSystem"].ToLower())
                {
                    case "metric":
                        return UnitSystem.Metric;
                    case "english":
                        return UnitSystem.English;
                    default:
                        mSettings["UnitSystem"] = "metric";
                        return UnitSystem.Metric;
                }
            }
            set
            {
                switch (value)
                {
                    case UnitSystem.Metric:
                        mSettings["UnitSystem"] = "metric";
                        break;
                    case UnitSystem.English:
                        mSettings["UnitSystem"] = "english";
                        break;
                }
            }
        }

        public static GpsSettings GpsSettings
        {
            get
            {
                if (!mSettings.ContainsKey("GpsSettings"))
                {
                    mSettings.Add("GpsSettings", "auto");
                    return GpsSettings.Auto;
                }

                switch (mSettings["GpsSettings"].ToLower())
                {
                    case "auto":
                        return GpsSettings.Auto;
                    case "manual":
                        return GpsSettings.Manual;
                    default:
                        mSettings["GpsSettings"] = "auto";
                        return GpsSettings.Auto;
                }
            }
            set
            {
                switch (value)
                {
                    case GpsSettings.Auto:
                        mSettings["GpsSettings"] = "auto";
                        break;
                    case GpsSettings.Manual:
                        mSettings["GpsSettings"] = "manual";
                        break;
                }
            }
        }

        public static void Save()
        {
            XmlWriter writer = null;

            try
            {
                XmlWriterSettings settings = new XmlWriterSettings();

                // create the xml file stream
                writer = XmlWriter.Create(mSettingsPath);
                writer.WriteStartDocument();

                //  <configuration>
                writer.WriteStartElement("configuration");

                //      <appSettings>
                writer.WriteStartElement("appSettings");

                foreach (KeyValuePair<string, string> setting in mSettings)
                {
                    writer.WriteStartElement("add");
                    writer.WriteAttributeString("key", setting.Key);
                    writer.WriteAttributeString("value", setting.Value);
                    writer.WriteEndElement();
                }

                //      </appState>
                writer.WriteEndElement();

                //  </configuration>
                writer.WriteEndElement();

                writer.WriteEndDocument();

                writer.Close();
                writer = null;
            }
            catch
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }

        private static void createSettingsFile()
        {
            XmlWriter writer = null;

            try
            {
                // create the xml file stream
                writer = XmlWriter.Create(mSettingsPath);
                writer.WriteStartDocument();

                //  <configuration>
                writer.WriteStartElement("configuration");

                //      <appSettings>
                writer.WriteStartElement("appSettings");

                //          <add key="GpsPort" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "GpsSettings");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //          <add key="GpsPort" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "GpsReadTimeout");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //          <add key="GpsPort" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "GpsPort");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //          <add key="GpsBaudRate" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "GpsBaudRate");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();


                //          <add key="UnitSystem" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "UnitSystem");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //      </appSettings>
                writer.WriteEndElement();

                //      <appState>
                writer.WriteStartElement("appState");

                //          <add key="MapViewLastLatitude" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "MapViewLastLatitude");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //          <add key="MapViewLastLongitude" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "MapViewLastLongitude");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //          <add key="MapViewLastMapPath" value="" />
                writer.WriteStartElement("add");
                writer.WriteAttributeString("key", "MapViewLastMapPath");
                writer.WriteAttributeString("value", string.Empty);
                writer.WriteEndElement();

                //      </appState>
                writer.WriteEndElement();

                //  </configuration>
                writer.WriteEndElement();

                writer.WriteEndDocument();

                writer.Close();
                writer = null;
            }
            catch
            {
                if (writer != null)
                {
                    writer.Close();
                }

                throw new Exception("Error creating application settings file.");
            }
        }
    }
}